package com.xh.poster.core.decorators;

import com.xh.poster.core.abst.AbstractPosterDecorator;
import com.xh.poster.core.abst.Poster;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;

/**
 * 背景 (绘制的模板,无需成为别人的装饰)
 *
 * @author yangXS
 * @date 2020/11/21
 * @since 1.0
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class BackgroundDecorator extends AbstractPosterDecorator {

    /**
     * 背景图
     */
    private BufferedImage bgImage;

    private boolean radius;

    private Integer radiusVal;

    public BackgroundDecorator() {
        super(null);
    }

    @Builder(toBuilder = true)
    public BackgroundDecorator(Poster poster, int positionX, int positionY, int width, int height, boolean radius, Integer radiusVal, BufferedImage bgImage) {
        super(poster, positionX, positionY, width, height);
        this.radius = radius;
        this.radiusVal = radiusVal;
        this.bgImage = bgImage;
    }


    @Override
    public BufferedImage draw(BufferedImage image) {
        // 装饰, 绘制背景
        return drawBackground(bgImage);
    }

    /**
     * 绘制背景具体实现
     *
     * @param image image
     * @return image
     */
    private BufferedImage drawBackground(BufferedImage image) {

        // 如果宽度没变化, 或者没设置
        if (width == 0 || height == 0) {
            return image;
        }
        // 调整背景宽度
        if (width != image.getWidth() || height != image.getHeight()) {
            BufferedImage newImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
            Graphics2D g = newImage.createGraphics();
            g.setStroke(new BasicStroke(0));
            g.drawImage(image, 0, 0, width, height, null);
            g.dispose();
            if (radius) {
                return setRadius(newImage, radiusVal, 0, 0);
            }
            return newImage;
        }
        // 绘制背景
        return image;
    }

    /**
     * 图片设置圆角
     *
     * @param srcImage 输入流
     * @param radius   圆角值
     * @param border   边框宽
     * @param padding  padding值
     * @return {@link BufferedImage}
     */
    public static BufferedImage setRadius(BufferedImage srcImage, int radius, int border, int padding) {
        int width = srcImage.getWidth();
        int height = srcImage.getHeight();
        int canvasWidth = width + padding * 2;
        int canvasHeight = height + padding * 2;

        BufferedImage image = new BufferedImage(canvasWidth, canvasHeight, BufferedImage.TYPE_INT_ARGB);
        Graphics2D gs = image.createGraphics();
        gs.setComposite(AlphaComposite.Src);
        gs.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        gs.setColor(Color.WHITE);
        gs.fill(new RoundRectangle2D.Float(0, 0, canvasWidth, canvasHeight, radius, radius));
        gs.setComposite(AlphaComposite.SrcAtop);
        gs.drawImage(setClip(srcImage, radius), padding, padding, null);
        if (border != 0) {
            gs.setColor(Color.GRAY);
            gs.setStroke(new BasicStroke(border));
            gs.drawRoundRect(padding, padding, canvasWidth - 2 * padding, canvasHeight - 2 * padding, radius, radius);
        }
        gs.dispose();
        return image;
    }

    /**
     * 图片设置圆角
     *
     * @param srcImage 图片流
     * @return {@link BufferedImage}
     */
    public static BufferedImage setRadius(BufferedImage srcImage) {
        int radius = (srcImage.getWidth() + srcImage.getHeight()) / 6;
        return setRadius(srcImage, radius, 2, 5);
    }

    /**
     * 图片切圆角
     *
     * @param srcImage 图片流
     * @param radius   圆角值
     * @return {@link BufferedImage}
     */
    public static BufferedImage setClip(BufferedImage srcImage, int radius) {
        int width = srcImage.getWidth();
        int height = srcImage.getHeight();
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D gs = image.createGraphics();

        gs.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        gs.setClip(new RoundRectangle2D.Double(0, 0, width, height, radius, radius));
        gs.drawImage(srcImage, 0, 0, null);
        gs.dispose();
        return image;
    }


}
